//
// Created by Sugars Mac on 2020/5/26.
//

#include <stdio.h>
#include <stdlib.h>     // exit
#include <string.h>
#include <unistd.h>     // bind listen
#include <time.h>       // time(NULL)   ctime(&ticks)
#include <netinet/in.h>
#include <arpa/inet.h>  // inet_ntop
#include <pthread.h>

#include "Datars.h"   //

void quit();

int main()
{
    struct sockaddr_in serv_addr, cli_addr;
//      int len = sizeof(cli_addr), i;
    int i;
    time_t ticks;
    pthread_t thread;
    char buff[BUFFSIZE];

    list = (relationMap*)malloc(sizeof(relationMap));
    list->next = NULL;

    printf("running...\n(Prompt: enter command ""quit"" to exit server)\n");
    DEBUG("=== initialize...");     //
    bzero(&serv_addr, sizeof(struct sockaddr_in));
    serv_addr.sin_family = AF_INET;
    serv_addr.sin_port = htons(PORT);
    serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);

    DEBUG("=== socket..."); //
    listenfd = socket(AF_INET, SOCK_STREAM, 0);
    if(listenfd < 0)
    {
        perror("fail to socket");
        exit(-1);
    }

    DEBUG("=== bind...");   //
    if(bind(listenfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0)
    {
        perror("fail to bind");
        exit(-2);
    }

    DEBUG("=== listening..."); //
    listen(listenfd, MAXMEM);

    pthread_create(&thread, NULL, (void *)(quit), NULL);

    // 初始化登陆用户的数据结构
    for(i=0; i<MAXMEM; i++) {
        users[i].sockfd = -1;
        users[i].username = NULL;
        users[i].groupid = -1;
    }
    // 初始化聊天室数据结构
    for(i = 0; i < MAXMEM; i++){
        rooms[i].roompass = NULL;
        rooms[i].roomname = NULL;
    }
    // 初始化注册用户表
    head = (TableList_t *)malloc(sizeof(TableList_t));
    head->data = NULL;
    head->next = NULL;
    readFromFile(head);

    while(1)
    {
        int len;// = sizeof(cli_addr);
        for(i=0; i<MAXMEM; i++)
        {
            if(users[i].sockfd == -1)
                break;
        }
        if(i == MAXMEM){ // 未找到空闲的描述符位置
            continue;
        }
        // accept
        users[i].sockfd = accept(listenfd, (struct sockaddr *)&cli_addr, &len);
        if(users[i].sockfd < 0)
        {
            perror("fail to accept");
            //      continue;
        }
        ticks = time(NULL);
        //sprintf(buff, "%.24s\r\n", ctime(&ticks));
        printf("%.24s\n\tconnect from: %s, port %d\n",
               ctime(&ticks), inet_ntop(AF_INET, &(cli_addr.sin_addr), buff, BUFFSIZE),
               ntohs(cli_addr.sin_port));      // inet_ntop #include <arpa/inet.h>

        pthread_create(malloc(sizeof(pthread_t)), NULL, (void *)(&rcv_snd), (void *)i);
    }
    return 0;
}

void quit()
{
    char msg[10];
    while(1)
    {
        scanf("%s", msg);       //
        if(strcmp(msg, "quit") == 0)
        {
            printf("Byebye... \n");
            deleteAllRela(list);

            writeToFile(head); // 保存注册用户信息
            destroyTable(head);

            close(listenfd);
            exit(0);
        }
    }
}
